mod json_helper;
use serde_json::{json, Value};

fn main() {
  use json_helper::{file_to_json, json_to_file};
  let config_file = "setini.json";
  let json = file_to_json(config_file).unwrap_or_else(|| {
    let default = json!({
    "base_dir": "D:/tcsoftV6",
    "files": ["gxcw60/TC.ini","grsr60/TC.ini","yhdz60/TC.ini","gzgl60/rlgz.ini"],
    "servers": ["127.0.0.1", "192.168.100.4"],
    });
    if let Err(e) = json_to_file(&default, config_file) {
      println!("写{}发生错误:{:?}", config_file, e);
    }
    default
  });

  let config = Config::new(&json);
  config.execute();
}

struct Config<'a> {
  base_dir: &'a str,
  files: Vec<&'a str>,
  servers: Vec<&'a str>,
}
impl<'a> Config<'a> {
  pub fn new(json: &'a Value) -> Self {
    use json_helper::JsonHelper;
    Self {
      base_dir: json["base_dir"].str(""),
      files: json["files"].str_list(""),
      servers: json["servers"].str_list(""),
    }
  }
  pub fn execute(&self) {
    use encoding_rs::GB18030;
    use std::{
      fs::File,
      io::{Read, Write},
    };
    fn setup(base_dir: &str, file: &str, server: &str) {
      fn read_ini(path: &str) -> Result<String, std::io::Error> {
        let mut file = File::open(path)?;
        let mut buffer = Vec::new();
        file.read_to_end(&mut buffer)?;
        let (result, _, _) = GB18030.decode(&buffer);
        Ok(result.into_owned())
      }
      fn write_ini(path: &str, content: &str) -> Result<(), std::io::Error> {
        let mut file = File::create(path)?;
        let (encoded, _, _) = GB18030.encode(content);
        file.write_all(&encoded)?;
        Ok(())
      }
      let file = format!("{base_dir}/{file}").replace('/', "\\");
      let content = read_ini(&file).unwrap_or_default();
      if content.is_empty() {
        println!("读取配置文件 {file} 失败！");
      } else if server.is_empty() {
        println!(">> {file}\n{content}");
      } else {
        let content = content
          .split("\r\n")
          .map(|line| {
            let upper_line = line.trim().to_uppercase();
            if upper_line.starts_with("SERVERNAME=") {
              format! {"SERVERNAME={server}"}
            } else if upper_line.starts_with("FWQMC=") {
              format! {"fwqmc={server}"}
            } else {
              line.to_owned()
            }
          })
          .collect::<Vec<String>>()
          .join("\r\n");
        println!("变更配置文件 {file} 将服务器设置为 {server}");
        write_ini(&file, &content).expect("写入{file}发生错误");
      }
    }

    let server = self.select();
    self.files.iter().for_each(|file| {
      setup(self.base_dir, file, server);
    });
    prompt("按回车键退出！");
  }

  fn select(&self) -> &str {
    let joined = self
      .servers
      .iter()
      .enumerate()
      .map(|(i, ip)| format!("    {}. {}", i, ip))
      .collect::<Vec<_>>()
      .join("\n");
    let msg=format!("下面将切换天财软件的数据库服务器:\n{joined}\n请输入数字 0-{} 选择服务器，输入其他值显示当前配置:",self.servers.len()-1);
    let choice = prompt(&msg);
    match choice.trim().parse::<usize>() {
      Ok(i) if i < self.servers.len() => self.servers[i],
      _ => "",
    }
  }
}
fn prompt(msg: &str) -> String {
  println!("{msg}");
  let mut choice = String::new();
  std::io::stdin()
    .read_line(&mut choice)
    .expect("读取键盘输入出错");
  choice
}
